package com.yunban.project.api.text_check.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencentcloudapi.common.SSEResponseModel;
import com.tencentcloudapi.lkeap.v20240522.LkeapClient;
import com.tencentcloudapi.lkeap.v20240522.models.ChatCompletionsRequest;
import com.tencentcloudapi.lkeap.v20240522.models.ChatCompletionsResponse;
import com.tencentcloudapi.lkeap.v20240522.models.Message;
import com.yunban.project.api.text_check.domain.ContentPolishRecord;
import com.yunban.project.api.text_check.domain.CorrectionConfig;
import com.yunban.project.api.text_check.dto.ContentPolishReq;
import com.yunban.project.api.text_check.enums.CorrectionModel;
import com.yunban.project.api.text_check.mapper.ContentPolishRecordMapper;
import com.yunban.project.api.text_check.service.ContentPolishService;
import com.yunban.project.api.text_check.service.CorrectionConfigService;
import com.yunban.project.api.text_check.utils.CorrectUtils;
import com.yunban.project.api.text_check.vo.ContentPolishResp;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.base.common.exception.BusinessException;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author: lijiajun
 * @date: 2025-02-17
 * @version: 1.0
 */
@Slf4j
@Service
public class ContentPolishServiceImpl extends ServiceImpl<ContentPolishRecordMapper, ContentPolishRecord> implements ContentPolishService {

    @Resource
    private CorrectionConfigService correctionConfigService;


    @Override
    public long saveContentPolishRecord(String text) {
        ContentPolishRecord contentPolishRecord = new ContentPolishRecord();
        contentPolishRecord.setText(text);
        this.save(contentPolishRecord);
        return contentPolishRecord.getId();
    }

    @SneakyThrows
    @Override
    public SseEmitter polish(ContentPolishReq req) {
        // 获取Deepseek的api配置
        CorrectionConfig config = correctionConfigService.findByCode(CorrectionModel.DEEPSEEK);
        if (ObjectUtils.isEmpty(config)) {
            throw new BusinessException("未配置Deepseek的api");
        }
        if (ObjectUtils.isEmpty(config.getApiKey()) || ObjectUtils.isEmpty(config.getApiSecret())) {
            throw new BusinessException("未配置Deepseek的api的可以与请求密钥");
        }
        // 首先将这个记录save到记录表中
        long rId = this.saveContentPolishRecord(req.getText());
        LkeapClient lkeapClient = CorrectUtils.getLkeapClient(config);
        // 实例化一个请求对象,每个接口都会对应一个request对象
        ChatCompletionsRequest dReq = new ChatCompletionsRequest();
        dReq.setModel("deepseek-v3");

        // body system
        Message[] messages1 = new Message[1];
        Message message1 = new Message();
        message1.setRole("user");
        // 前置系统提示词
//        message1.setContent("#角色名称: 文本润色助手\n" + "#风格特点:\n" + "1. 处理过程保持绝对中立，对涉及敏感/政治相关内容进行自动过滤\n" + "2. 不返回除了润色文本以外的任何内容\n" + "#能力限制: 不处理超过5000字的批量文本任务\n" + "\n" + "需润色文本：" + req.getText());
        message1.setContent(req.getText() + " 请对以上文章进行润色");
        messages1[0] = message1;
        dReq.setMessages(messages1);
        // 非流式响应
        dReq.setStream(true);
        // 返回的resp是一个ChatCompletionsResponse的实例，与请求对象对应
        ChatCompletionsResponse resp = lkeapClient.ChatCompletions(dReq);
        // 输出json格式的字符串回包
        // 判断是否是流式响应
        SseEmitter emitter = new SseEmitter(180_000L);
        ExecutorService executorService = Executors.newSingleThreadExecutor();

        if (resp.isStream()) {
            executorService.execute(() -> {
                for (SSEResponseModel.SSE e : resp) {
                    String data = e.Data;
                    log.info("文本润色结果:{}", data);
                    try {
                        JSONObject result = JSON.parseObject(data);
                        emitter.send(SseEmitter.event().data(result).name("answer").id(rId + ""));
                    } catch (Exception ex) {
                        log.error("文本润色失败！", ex);
                        log.error("文本润色失败:{}", ex.getMessage());
                        emitter.completeWithError(ex);
                        throw new BusinessException("文本润色失败:" + ex.getMessage());
                    }
                }
                emitter.complete();
            });
        }
        return emitter;
    }
}
